//	CP2013 Traffic Simulator Assignment
//      Traffic Model Intersection
//	Java version
//      Coded by Matthew Johnson


package traffic;
import java.util.Vector;

//This class holds information about the intersection in the model
public class Intersection
{
    //Embedded class used for storing sets of traffic light states to cycle between
    private class IntersectionState
    {
        public LightState horizontal;
        public LightState vertical;

        IntersectionState(LightState h, LightState v)
        {
            horizontal = h;
            vertical = v;
        }
    }
    //The default length of a green light
    public static final int DEFAULT_GREEN_LENGTH = 5;
    //The coordinates of the top left corner of the intersection
    private Coordinate anchor;
    //The intersection's current direction
    private char direction;
    //The intersection's size
    private int width;
    private int height;
    //The two traffic lights controlling the intersection
    private TrafficLight hLight;
    private TrafficLight vLight;
    //The current 'state' of the light cycle
    private int cycleIndex;
    //The length of a green light;
    private int greenLength;
    //The states to cycle through
    private Vector<IntersectionState> statesCycle;

    //Getters and setters
    public TrafficLight getHLight()
    {
        return hLight;
    }

    public void setHLight(TrafficLight hLight)
    {
        this.hLight = hLight;
    }

    public TrafficLight getVLight()
    {
        return vLight;
    }

    public void getVLight(TrafficLight vLight)
    {
        this.vLight = vLight;
    }

        public char getDirection()
    {
        return direction;
    }

    public void setDirection(char direction)
    {
        this.direction = direction;
    }

    public int getHeight()
    {
        return height;
    }

    public void setHeight(int height)
    {
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width)
    {
        this.width = width;
    }

    public Coordinate getAnchor()
    {
        return anchor;
    }

    public void setAnchor(Coordinate anchor)
    {
        this.anchor = anchor;
    }

    //Constructor: Initialises the intersection to the provided size with default cycle lengths
    Intersection(int wid, int hei)
    {
        //Initialise the class variables
        width = wid;
        height = hei;
        greenLength = DEFAULT_GREEN_LENGTH;
        hLight = new TrafficLight();
        vLight = new TrafficLight();
        statesCycle = new Vector<IntersectionState>();

        //Setup the possible states
        IntersectionState vGreen  = new IntersectionState(LightState.GREEN  ,LightState.RED);
	IntersectionState vYellow = new IntersectionState(LightState.YELLOW ,LightState.RED);
	IntersectionState hGreen  = new IntersectionState(LightState.RED    ,LightState.GREEN);
	IntersectionState hYellow = new IntersectionState(LightState.RED    ,LightState.YELLOW);

        //Setup the cycle of states
        for (int i = 0; i < greenLength; ++i)
            statesCycle.add(vGreen);
        statesCycle.add(vYellow);
        for (int i = 0; i < greenLength; ++i)
		statesCycle.add(hGreen);
	statesCycle.add(hYellow);
        setState(0);
    }

    //Move to the next state in the cycle
    public void cycleState()
    {
	setState(cycleIndex + 1);
    }

    //Checks if one of the lights is yellow
    public boolean yellowOn()
    {
        return (hLight.state == LightState.YELLOW || vLight.state == LightState.YELLOW);
    }

    //Sets the Intersection's current state
    void setState(int n){
	//For numbers larger than the greatest index, roll over
	n = n % statesCycle.size();

	//Update the traffic lights
	vLight.state = statesCycle.get(n).vertical;
	hLight.state = statesCycle.get(n).horizontal;

	//Update the cycle index
	cycleIndex = n;
    }


}
